#include<chrono>
#include<iostream>
#include<thread>
#include<fstream>
#include<sys/syscall.h>
#include<sys/prctl.h>
#include<unistd.h>
#include<sys/sysinfo.h>

int64_t GetTotalCpuOccupy(void) {
    std::ifstream ifs("/proc/stat");
    std::string cpu_name;

    ifs>> cpu_name;

    int64_t cpu_time = 0;
    int64_t item_time = 0;
    for (int i = 0; i < 9; i++) {
        ifs>> item_time;
        cpu_time += item_time;
    }

    return cpu_time;
}

int64_t GetThreadCpuOccupy(int tid) {
    std::string file_name = std::string("/proc/self/task/") + std::to_string(tid) + "/stat";
    std::ifstream ifs(file_name);

    std::string str_skip;
    for (int i = 0; i < 13; i++) {
        ifs >> str_skip;
    }

    int64_t user_time, system_time;
    ifs>> user_time >> system_time;

    return user_time + system_time;
}

void MyThread(void)
{
    prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("sub_thread"), 0, 0, 0);

    std::chrono::steady_clock::time_point time_start = std::chrono::steady_clock::now();
    int64_t last_cpu_time = GetTotalCpuOccupy();
    
    int tid = syscall(SYS_gettid);
    int64_t last_thread_time = GetThreadCpuOccupy(tid);

    int cpu_cnt = get_nprocs();

    while (1)
    {
        for (int i = 0; i < 10000; i++)
        {

        }
        std::this_thread::sleep_for(std::chrono::microseconds(1));

        std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
        auto time_span = std::chrono::duration_cast<std::chrono::milliseconds>(now - time_start);
        auto count = time_span.count();

        if (count > 1000)
        {
            int64_t cur_cpu_time = GetTotalCpuOccupy();
            int64_t cur_thread_time = GetThreadCpuOccupy(tid);

            double cpu_percent = (cur_thread_time - last_thread_time) * cpu_cnt * 100.0 / (cur_cpu_time - last_cpu_time);
            std::cout<< " sub thread cpu percent: " << cpu_percent << "%" << std::endl;

            last_thread_time = cur_thread_time;
            last_cpu_time = cur_cpu_time;
            time_start = now;
        }
    }

}

int main(void)
{
    std::thread t1(MyThread);

    while (1)
    {
        std::chrono::steady_clock::time_point time_start = std::chrono::steady_clock::now();
		int64_t last_cpu_time = GetTotalCpuOccupy();
		
		int tid = syscall(SYS_gettid);
		int64_t last_thread_time = GetThreadCpuOccupy(tid);

		int cpu_cnt = get_nprocs();

		while (1)
		{
			for (int i = 0; i < 100; i++)
			{

			}
			std::this_thread::sleep_for(std::chrono::microseconds(1));

			std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
			auto time_span = std::chrono::duration_cast<std::chrono::milliseconds>(now - time_start);
			auto count = time_span.count();

			if (count > 1000)
			{
				int64_t cur_cpu_time = GetTotalCpuOccupy();
				int64_t cur_thread_time = GetThreadCpuOccupy(tid);

				double cpu_percent = (cur_thread_time - last_thread_time) * cpu_cnt * 100.0 / (cur_cpu_time - last_cpu_time);
				std::cout<< " main cpu percent: " << cpu_percent << "%" << std::endl;

				last_thread_time = cur_thread_time;
				last_cpu_time = cur_cpu_time;
				time_start = now;
			}
		}
    }
}
